<template>
  <div>
    <!-- 面包屑导航 -->
    <el-breadcrumb separator-class="el-icon-arrow-right">
      <el-breadcrumb-item :to="{ path: '/' }">首页</el-breadcrumb-item>
      <el-breadcrumb-item>权限管理</el-breadcrumb-item>
      <el-breadcrumb-item>角色列表</el-breadcrumb-item>
    </el-breadcrumb>
    <!-- 卡片区域 -->
    <el-card>
      <el-row>
        <el-col>
          <el-button type="primary">新增角色</el-button>
        </el-col>
      </el-row>
    </el-card>
    <!-- 表格区域 -->
    <el-table :data="roleList" style="width: 100%" border stripe row-key="id">
      <!-- 展开列 显示三级权限-->
      <el-table-column type="expand">
        <template slot-scope="scope">
          <!-- 循环一级权限  循环行 -->
          <el-row
            v-for="(item1, index1) in scope.row.children"
            :key="item1.id"
            :class="['bottomBorder', index1 == 0 ? 'topBorder' : '', 'venter']"
          >
            <!-- 一级权限左边列 -->
            <el-col :span="5">
              <el-tag closable @close="delRightById(scope.row, item1.id)">{{
                item1.authName
              }}</el-tag>
              <!-- 图标 -->
              <i class="el-icon-caret-right"></i>
            </el-col>
            <!-- 一级权限右边列 二级权限 循环行-->
            <el-col :span="19">
              <el-row
                :class="[index2 == 0 ? '' : 'topBorder', 'venter']"
                v-for="(item2, index2) in item1.children"
                :key="item2.id"
              >
                <!-- 二级权限左边列  -->
                <el-col :span="6">
                  <el-tag
                    type="success"
                    closable
                    @close="delRightById(scope.row, item2.id)"
                    >{{ item2.authName }}</el-tag
                  >
                  <i class="el-icon-caret-right"></i>
                </el-col>
                <!-- 二级权限左边列 三级权限  -->
                <el-col :span="18">
                  <el-tag
                    closable
                    @close="delRightById(scope.row, item3.id)"
                    type="warning"
                    v-for="item3 in item2.children"
                    :key="item3.id"
                    >{{ item3.authName }}</el-tag
                  >
                </el-col>
              </el-row>
            </el-col>
          </el-row>
        </template>
      </el-table-column>
      <el-table-column type="index" label="#"></el-table-column>
      <el-table-column prop="roleName" label="角色名称"> </el-table-column>
      <el-table-column prop="roleDesc" label="角色描述"> </el-table-column>
      <el-table-column label="操作">
        <template slot-scope="scope">
          <el-button size="mini" type="primary" icon="el-icon-edit"
            >编辑</el-button
          >
          <el-button size="mini" type="danger" icon="el-icon-delete"
            >删除</el-button
          >
          <el-button
            size="mini"
            type="warning"
            icon="el-icon-setting"
            @click="ShowRightDialog(scope.row)"
            >分配权限</el-button
          >
        </template>
      </el-table-column>
    </el-table>

    <!-- 权限对话框 -->
    <el-dialog title="分配权限" :visible.sync="isShowDialog" width="50%">
      <!-- 树形结构菜单 -->
      <el-tree
        :data="treeList"
        :props="treeProps"
        show-checkbox
        default-expand-all
        node-key="id"
        :default-checked-keys="checkedKeys"
        ref="rightTree"
      ></el-tree>
      <span slot="footer" class="dialog-footer">
        <el-button @click="isShowDialog = false">取 消</el-button>
        <el-button type="primary" @click="setRoleRights">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
  created () {
    // 获取角色列表
    this.getRoleList()
  },
  data () {
    return {
      // 角色列表
      roleList: [],
      // 分配权限弹出框
      isShowDialog: false,
      // 树形菜单权限数据
      treeList: [],
      // 树形菜单 配置对象
      treeProps: {
        label: 'authName'
      },
      // 跟 默认展开属性 node-key配套使用的数组
      checkedKeys: [],
      // 当前选中的角色id
      roleId: ''
    }
  },
  methods: {
    // 获取角色列表
    async getRoleList () {
      const { data: res } = await this.$http.get('roles')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.$message.success(res.meta.msg)
      this.roleList = res.data
    },
    // 删除角色  所有级别都用
    delRightById (scopeRow, rightId) {
      this.$messageBox.confirm('确定要删除吗？', '系统提示', {
        confirmButtonText: '确定',
        callback: async (action) => {
          // 删除操作
          if (action === 'cancel') return
          // 请求删除角色制定权限接口 根据接口 会删除该数据并返回新数据
          const { data: res } = await this.$http.delete(
            `roles/${scopeRow.id}/rights/${rightId}`
          )
          if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
          // 刷新角色权限视图
          scopeRow.children = res.data
        }
      })
    },
    // 显示分配角色对话框
    async ShowRightDialog (rowData) {
      // 调用前先清空该数组
      this.checkedKeys = []

      this.roleId = rowData.id
      // 获取权限列表
      const { data: res } = await this.$http.get('rights/tree')
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      this.treeList = res.data
      // 显示对话框内的小复选框方法 rowData 是一个对象 只能传children数组给参数用foreach遍历
      this.getRightIds(rowData.children)
      this.isShowDialog = true
    },
    // 匹配id值 显示勾选
    getRightIds (rowList) {
      rowList.forEach((ele) => {
        // 如果有children 再次递归遍历
        if (ele.children) {
          this.getRightIds(ele.children)
        } else {
          // 没有children 就将该元素的id 追加进checkedKeys数组
          this.checkedKeys.push(ele.id)
        }
      })
    },
    // 分配角色权限 确定按钮点击事件
    async setRoleRights () {
      // 通过element-ui方法 获取当前要修改权限的 角色id 根据接口，需要转化成','分隔的字符串 组合成新的数组
      const a = this.$refs.rightTree.getCheckedKeys()
      const b = this.$refs.rightTree.getHalfCheckedKeys()
      const rightIds = [...a, ...b]
      const strIds = rightIds.join(',')
      // 发起请求
      const { data: res } = await this.$http.post(`roles/${this.roleId}/rights`, {
        rids: strIds
      })
      if (res.meta.status !== 200) return this.$message.error(res.meta.msg)
      // 请求成功
      this.getRoleList()
      // 关闭对话框
      this.isShowDialog = false
    }
  }
}
</script>

<style lang="less" scoped>
.el-tag {
  margin: 7px;
}
.topBorder {
  border-top: 1px solid #eee;
}
.bottomBorder {
  border-bottom: 1px solid #eee;
}
.vcenter {
  display: flex;
  align-items: center;
}
</style>
